/**
 * Created by Egan on 2015/1/17.
 */
module catgame{

    export class Map extends egret.DisplayObjectContainer{

        private map:any[]=[];
        private mapsize: number = 9; //必须奇数
        private playTurn:boolean=true;
        private block:number=0.2;

        public tap:number=0;

        public constructor(){
            super();
            this.addEventListener(egret.Event.ADDED_TO_STAGE,this.onAddToStage,this);
        }

        private onAddToStage(event:egret.Event){
            this.removeEventListener(egret.Event.ADDED_TO_STAGE,this.onAddToStage,this);
        }

        public init(){
            while(this.numChildren){
                this.removeChildAt(0);
            }

            this.map=[];
            this.createMap();
            this.tap=0;
        }

        /**
         * 创建地图
         */
        private createMap(){
            var node:catgame.Node;
            for(var i:number=0;i<this.mapsize;i++){
                this.map[i]=[];
                for(var j:number=0;j<this.mapsize;j++){
                    node=new catgame.Node(i,j);
                    node.x=i*48+(j%2)*24;
                    node.y=j*44;
                    this.map[i][j]=node;
                    node.touchEnabled=true;
                    node.addEventListener(egret.TouchEvent.TOUCH_TAP,this.onNodeClick,this);
                    this.addChild(node);

                    var cc:number=(this.mapsize-1)/2;
                    if(i!=cc&&j!=cc&&Math.random()<this.block){
                        node.doFillPot();
                        node.touchEnabled=false;
                    }
                }
            }
        }

        /**
         * 地图点被点击
         * @param event
         */
        private onNodeClick(event:egret.TouchEvent):void{
            if(!this.playTurn) {
                //猫咪跳
                console.log("现在轮到猫咪了");
                return;
            }

            this.tap=this.tap+1;
            var node:catgame.Node=event.target;
            node.doFillPot();
            node.touchEnabled=false;
            node.removeEventListener(egret.TouchEvent.TOUCH_TAP,this.onNodeClick,this);

            this.dispatchEventWith("nodeClick");
        }

        /**
         * 是否是出口
         * @param _node
         */
        public isExit(_node:catgame.Node){
            var sd:number[]=_node.getPos();
            if(sd[0]==0||sd[1]==0||sd[0]==this.mapsize-1||sd[1]==this.mapsize-1){
                return true;
            }

            return false;
        }

        /**
         * 猫咪寻路
         * @param _from
         */
        public findPath(_from:catgame.Node){
            var node:catgame.Node;
            for(var i:number=0;i<this.mapsize;i++){
                for(var j:number=0;j<this.mapsize;j++){
                    node=this.map[i][j];
                    node.clean();
                }
            }

            node=this.findNode(_from);

            var path:any[]=[];
            if(node){
                while(node.prenode){
                    path.push(node.getPos());
                    node=node.prenode;
                }
            }else{
                console.log("已经被困随便走一步");
                this.dispatchEventWith("weizhu");
                //随便走一步
                path = this.getNear(_from);
            }

            return path.reverse();

        }

        /**获得可走的点**/
        public getNear(__node: catgame.Node){
            var pos:number[] = __node.getPos();
            var arr:any[] = this.getRound(pos);
            var l:number = arr.length;
            for(var i :number = 0 ; i < l ; i++){
                if(!this.getNode(arr[i]).isFill()){
                    return [arr[i]];
                }
            }
            return [];
        }

        private findNode(_from:catgame.Node){
            var used:catgame.Node[]=[_from];
            var next:catgame.Node[]=[_from];
            var flag:boolean=true;
            var around:any[];

            var i:number=0;
            var l:number=0;
            var j:number=0;
            var k:number=0;
            var node:catgame.Node;
            var tnode:catgame.Node;
            while(flag){
                l=next.length
                console.log("寻路中..." + l);

                if(l==0){
                    flag=false;
                    return null;
                }

                var tnext:catgame.Node[]=[];
                for(i=0;i<l;i++){
                    node=next.shift();
                    around=this.getRound(node.getPos());
                    k=around.length;
                    console.log("下一层路点..." + k)
                    for(j=0;j<k;j++){
                        var rnd:number[]=around[j];
                        tnode=this.map[rnd[0]][rnd[1]];
                        if(tnode.isFill()){
                            //不可走
                            used.push(tnode);
                            continue;
                        }
                        if(used.indexOf(tnode)>-1||next.indexOf(tnode)>-1){
                            //已经计算过了,或者已经在下一轮计算备选中了
                            continue;
                        }
                        tnode.prenode=node;
                        if(this.isExit(tnode)){
                            console.log("找到出口，最短路径")
                            return tnode;
                        }
                        tnext.push(tnode);
                    }
                    used.push(node);
                }
                next=tnext;
            }
        }

        /**
         * 计算周围格子
         * @param _point
         */
        private getRound(_point:number[]){
            var xx:number=_point[0];
            var yy:number=_point[1];
            var arr:any[];
            var ret:any[]=[];
            if(yy%2==0){
                arr=[[xx-1,yy-1],[xx-1,yy],[xx-1,yy+1],[xx,yy+1],[xx+1,yy],[xx,yy-1]];
            }else{
                arr=[[xx,yy-1],[xx-1,yy],[xx,yy+1],[xx+1,yy+1],[xx+1,yy],[xx+1,yy-1]];
            }

            for(var i:number=0;i<6;i++){
                var rnd:number[]=arr[i];
                if(rnd[0]>=0&&rnd[1]>=0&&rnd[0]<this.mapsize&&rnd[1]<this.mapsize){
                    ret.push(rnd);
                }
            }

            return ret;
        }

        public getNode(arr:number[]){
            return this.map[arr[0]][arr[1]];
        }

        public coverPos2Point(_arr:number[]){
            return [this.x+48*_arr[0]+(_arr[1]%2)*24,this.y+_arr[1]*44];
        }

        public lock():void{
            this.playTurn=false;
        }

        public unlock():void{
            this.playTurn=true;
        }

    }
}